package de.koller.oceanFramework.util;

public class ColorIntUtil {
	
	public static final float BRIGHTER_FACTOR = 0.7f;
	public static final float DARKER_FACTOR = 0.7f;
	
	private ColorIntUtil() {}
	
	public static int brighter( int c ) {
		int r = (int)( (255f-(float)getRValue( c )) * BRIGHTER_FACTOR );
		int g = (int)( (255f-(float)getGValue( c )) * BRIGHTER_FACTOR );
		int b = (int)( (255f-(float)getBValue( c )) * BRIGHTER_FACTOR );
		return getIntColor( getAValue( c ), 255-r, 255-g, 255-b );
	}
	
	public static int darker( int c ) {
		int r = (int)( (float)getRValue( c ) * DARKER_FACTOR );
		int g = (int)( (float)getGValue( c ) * DARKER_FACTOR );
		int b = (int)( (float)getBValue( c ) * DARKER_FACTOR );
		return getIntColor( getAValue( c ), r, g, b );
	}
	
	public static int multiply( int c1, int c2 ) {
		int r = clampSegment( (int)( (float)getRValue(c1) * floatValue( getRValue(c2) ) ) );
		int g = clampSegment( (int)( (float)getGValue(c1) * floatValue( getGValue(c2) ) ) );
		int b = clampSegment( (int)( (float)getBValue(c1) * floatValue( getBValue(c2) ) ) );
		int a = clampSegment( (int)( (float)getAValue(c1) * floatValue( getAValue(c2) ) ) );
		return getIntColor( a, r, g, b );
	}
	
	public static int add( int c1, int c2 ) {
		int a = clampSegment( getAValue( c1 ) + getAValue( c2 ) );
		int r = clampSegment( getRValue( c1 ) + getRValue( c2 ) );
		int g = clampSegment( getGValue( c1 ) + getGValue( c2 ) );
		int b = clampSegment( getBValue( c1 ) + getBValue( c2 ) );
		return getIntColor( a, r, g, b );
	}
	
	public static int clampSegment( int v ) {
		if( v < 0 )
			return 0;
		if( v > 0xff )
			return 0xff;
		
		return v;
	}
	
	public static float floatValue( int v ) {
		return (float)v / 255f;
	}
	
	public static int getAValue( int v ) {
		return ( v >>> 24 ) & 0xff;
	}
	
	public static int getRValue( int v ) {
		return ( v >>> 16 ) & 0xff;
	}
	
	public static int getGValue( int v ) {
		return ( v >>> 8 ) & 0xff;
	}
	
	public static int getBValue( int v ) {
		return v & 0xff;
	}
	
	public static float getAValueF( int v ) {
		return floatValue( getAValue( v ) );
	}
	
	public static float getRValueF( int v ) {
		return floatValue( getRValue( v ) );
	}
	
	public static float getGValueF( int v ) {
		return floatValue( getGValue( v ) );
	}
	
	public static float getBValueF( int v ) {
		return floatValue( getBValue( v ) );
	}
	
	public static int getIntColor( int r, int g, int b ) {
		return (r << 16) | (g << 8) | b;
	}
	
	public static int getIntColor( int a, int r, int g, int b ) {
		return (a << 24) | (r << 16) | (g << 8) | b;
	}
	
	public static byte[] getRGBA( int c ) {
		return new byte[] {
			(byte)getRValue( c ),
			(byte)getGValue( c ),
			(byte)getBValue( c ),
			(byte)getAValue( c )
		};
	}
	
	/* set -1 if you want to keep the value. */
	public static int change( int argb, int a, int r, int g, int b ) {
		return ColorIntUtil.getIntColor( 
				a != -1 ? a : ColorIntUtil.getAValue( argb ),
				r != -1 ? r : ColorIntUtil.getRValue( argb ),
				g != -1 ? g : ColorIntUtil.getGValue( argb ),
				b != -1 ? b : ColorIntUtil.getBValue( argb )
		);
	}

	public static void main( String... args ) {
		System.out.println( Integer.toHexString( ColorIntUtil.change( 0x12345678, -1, 0xff, -1, -1 ) ) );
	}
}
